package com.quick.springbootquicky.interceptors;

import com.quick.springbootquicky.utils.JWTUtil;
import com.quick.springbootquicky.utils.RedisUtil;
import com.quick.springbootquicky.utils.Result;
import com.quick.springbootquicky.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

/**
 * 拦截器，但是拦截器每一个接口都会拦截
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 方法调用前执行,放开登入与注册接口 WebConfig
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            String token = request.getHeader("Authorization");
            if (null == token || token.isEmpty()) {
                throw new RuntimeException("token失效");
            }
            Map<String, Object> claims = JWTUtil.parseToken(token);
            // 当没找到 token，则认证失败
            if (null == claims) {
                throw new RuntimeException("没找到 token");
            }
            String username = (String) claims.get("username");
            // 当 token 没绑定用户，则认证失败
            if (null == username || username.isEmpty()) {
                throw new RuntimeException("token 没绑定用户");
            }
            String redisToken = RedisUtil.get(username+claims.get("id"));
            if(null==redisToken || !token.equals(redisToken)){
                throw new RuntimeException("token缺失");
            }
            //存储到当前线程中
            ThreadLocalUtil.set(claims);
            // 离临近过期还有30分钟时间在跟更新
            if (RedisUtil.getExpireTime(username+claims.get("id")) <1*60*30) {
                RedisUtil.set(username+claims.get("id"),token);
            }

            return true;
        }catch(Exception e){
            e.printStackTrace();
            response.setStatus(401);
            response.setContentType("text/html; charset=UTF-8");
            response.getWriter().write(e.getMessage());
            return false;
        }
    }

    /**
     * 方法调用完后执行，在此清除线程内存
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

        ThreadLocalUtil.remove();
    }



}
